การเพิ่มประสิทธิภาพกราฟโมดูล JavaScript: การทำให้กราฟ Dependency เรียบง่ายขึ้น | MLOG | MLOG
            document.addEventListener("DOMContentLoaded", function() {
 var lazyloadImages = document.querySelectorAll("img.lazy");

 function lazyload () {
 lazyloadImages.forEach(function(img) {
 if (img.offsetTop < (window.innerHeight + window.pageYOffset)) {
 img.src = img.dataset.src;
 img.classList.remove("lazy");
 }
 });
 if(lazyloadImages.length === 0) {
 document.removeEventListener("scroll", lazyload);
 window.removeEventListener("resize", lazyload);
 window.removeEventListener("orientationChange", lazyload);
 }
 }

 document.addEventListener("scroll", lazyload);
 window.addEventListener("resize", lazyload);
 window.addEventListener("orientationChange", lazyload);
 });
            

ข้อแนะนำที่นำไปปฏิบัติได้: ใช้ lazy loading สำหรับรูปภาพ, วิดีโอ, และทรัพยากรอื่นๆ ที่ยังไม่ปรากฏบนหน้าจอทันที พิจารณาใช้ไลบรารีอย่าง `lozad.js` หรือ attribute lazy-loading ที่มีมากับเบราว์เซอร์

6. Tree Shaking และ Dead Code Elimination

Tree shaking เป็นเทคนิคที่ลบโค้ดที่ไม่ได้ใช้ออกจากแอปพลิเคชันของคุณในระหว่างกระบวนการ build ซึ่งสามารถลดขนาด bundle ได้อย่างมาก โดยเฉพาะอย่างยิ่งถ้าคุณใช้ไลบรารีที่มีโค้ดจำนวนมากที่คุณไม่ต้องการ

ตัวอย่าง:

สมมติว่าคุณกำลังใช้ไลบรารี utility ที่มี 100 ฟังก์ชัน แต่คุณใช้เพียง 5 ฟังก์ชันในแอปพลิเคชันของคุณ หากไม่มี tree shaking ไลบรารีทั้งหมดจะถูกรวมอยู่ใน bundle ของคุณ แต่ด้วย tree shaking จะมีเพียง 5 ฟังก์ชันที่คุณใช้เท่านั้นที่จะถูกรวมเข้าไป

การตั้งค่า:

ตรวจสอบให้แน่ใจว่า bundler ของคุณได้รับการตั้งค่าให้ทำ tree shaking ใน webpack โดยปกติจะเปิดใช้งานโดยค่าเริ่มต้นเมื่อใช้ production mode ใน Rollup คุณอาจต้องใช้ปลั๊กอิน `@rollup/plugin-commonjs`

ข้อแนะนำที่นำไปปฏิบัติได้: ตั้งค่า bundler ของคุณให้ทำ tree shaking และตรวจสอบให้แน่ใจว่าโค้ดของคุณเขียนในลักษณะที่เข้ากันได้กับ tree shaking (เช่น การใช้ ES modules)

7. การลดจำนวน Dependencies

จำนวน dependency ในโปรเจกต์ของคุณส่งผลโดยตรงต่อความซับซ้อนของกราฟโมดูล แต่ละ dependency ที่เพิ่มเข้ามาในกราฟอาจเพิ่มเวลาในการ build และขนาดของ bundle ได้ ควรทบทวน dependency ของคุณเป็นประจำและลบสิ่งที่ไม่จำเป็นหรือสามารถแทนที่ด้วยทางเลือกที่เล็กกว่าได้

ตัวอย่าง:

แทนที่จะใช้ไลบรารี utility ขนาดใหญ่สำหรับงานง่ายๆ ลองพิจารณาเขียนฟังก์ชันของคุณเองหรือใช้ไลบรารีที่เล็กกว่าและเฉพาะทางกว่า

ข้อแนะนำที่นำไปปฏิบัติได้: ทบทวน dependency ของคุณเป็นประจำโดยใช้เครื่องมืออย่าง `npm audit` หรือ `yarn audit` และมองหาโอกาสในการลดจำนวน dependency หรือแทนที่ด้วยทางเลือกที่เล็กกว่า

8. การวิเคราะห์ขนาด Bundle และประสิทธิภาพ

วิเคราะห์ขนาด bundle และประสิทธิภาพของคุณเป็นประจำเพื่อหาจุดที่ต้องปรับปรุง เครื่องมืออย่าง webpack-bundle-analyzer และ Lighthouse สามารถช่วยคุณระบุโมดูลขนาดใหญ่, โค้ดที่ไม่ได้ใช้, และปัญหาคอขวดด้านประสิทธิภาพ

ตัวอย่าง (webpack-bundle-analyzer):

เพิ่มปลั๊กอิน `webpack-bundle-analyzer` ในการตั้งค่า webpack ของคุณ

            const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
 // ... other webpack configuration
 plugins: [
 new BundleAnalyzerPlugin()
 ]
};

            

เมื่อคุณรัน build ปลั๊กอินจะสร้างแผนที่ treemap แบบโต้ตอบที่แสดงขนาดของแต่ละโมดูลใน bundle ของคุณ

ข้อแนะนำที่นำไปปฏิบัติได้: ผสานเครื่องมือวิเคราะห์ bundle เข้ากับกระบวนการ build ของคุณ และตรวจสอบผลลัพธ์เป็นประจำเพื่อหาจุดที่ต้องปรับปรุง

9. Module Federation

Module Federation ซึ่งเป็นฟีเจอร์ใน webpack 5 ช่วยให้คุณสามารถแชร์โค้ดระหว่างแอปพลิเคชันต่างๆ ในขณะรันไทม์ได้ ซึ่งมีประโยชน์สำหรับการสร้าง microfrontends หรือสำหรับการแชร์ component ทั่วไประหว่างโปรเจกต์ต่างๆ Module Federation สามารถช่วยลดขนาด bundle และปรับปรุงประสิทธิภาพโดยหลีกเลี่ยงการทำซ้ำของโค้ด

ตัวอย่าง (การตั้งค่า Module Federation เบื้องต้น):

แอปพลิเคชัน A (Host):

            // webpack.config.js
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
 // ... other webpack configuration
 plugins: [
 new ModuleFederationPlugin({
 name: "appA",
 remotes: {
 appB: "appB@http://localhost:3001/remoteEntry.js",
 },
 shared: ["react", "react-dom"]
 })
 ]
};

            

แอปพลิเคชัน B (Remote):

            // webpack.config.js
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
 // ... other webpack configuration
 plugins: [
 new ModuleFederationPlugin({
 name: "appB",
 exposes: {
 './MyComponent': './src/MyComponent',
 },
 shared: ["react", "react-dom"]
 })
 ]
};

            

ข้อแนะนำที่นำไปปฏิบัติได้: พิจารณาใช้ Module Federation สำหรับแอปพลิเคชันขนาดใหญ่ที่มีโค้ดที่ใช้ร่วมกัน หรือสำหรับการสร้าง microfrontends

ข้อควรพิจารณาสำหรับ Bundler แต่ละตัว

Bundler แต่ละตัวมีจุดแข็งและจุดอ่อนที่แตกต่างกันเมื่อพูดถึงการเพิ่มประสิทธิภาพกราฟโมดูล นี่คือข้อควรพิจารณาบางประการสำหรับ bundler ที่เป็นที่นิยม:

Webpack

Rollup

Parcel

มุมมองระดับโลก: การปรับการเพิ่มประสิทธิภาพสำหรับบริบทที่แตกต่างกัน

เมื่อทำการเพิ่มประสิทธิภาพกราฟโมดูล สิ่งสำคัญคือต้องพิจารณาบริบทระดับโลกที่แอปพลิเคชันของคุณจะถูกนำไปใช้ ปัจจัยต่างๆ เช่น สภาพเครือข่าย, ความสามารถของอุปกรณ์, และข้อมูลประชากรของผู้ใช้ สามารถมีอิทธิพลต่อประสิทธิภาพของเทคนิคการเพิ่มประสิทธิภาพที่แตกต่างกัน

บทสรุป

การเพิ่มประสิทธิภาพกราฟโมดูล JavaScript เป็นส่วนสำคัญของการพัฒนา front-end โดยการทำให้ dependency เรียบง่ายขึ้น, ลบ circular dependencies, และใช้ code splitting คุณสามารถปรับปรุงประสิทธิภาพการ build, ลดขนาด bundle, และเพิ่มความเร็วในการโหลดแอปพลิเคชันได้อย่างมาก วิเคราะห์ขนาด bundle และประสิทธิภาพของคุณเป็นประจำเพื่อหาจุดที่ต้องปรับปรุง และปรับกลยุทธ์การเพิ่มประสิทธิภาพของคุณให้เข้ากับบริบทระดับโลกที่แอปพลิเคชันของคุณจะถูกนำไปใช้ จำไว้ว่าการเพิ่มประสิทธิภาพเป็นกระบวนการต่อเนื่อง และการตรวจสอบและปรับปรุงอย่างสม่ำเสมอเป็นสิ่งจำเป็นเพื่อให้ได้ผลลัพธ์ที่ดีที่สุด

ด้วยการใช้เทคนิคเหล่านี้อย่างสม่ำเสมอ นักพัฒนาทั่วโลกสามารถสร้างเว็บแอปพลิเคชันที่เร็วขึ้น, มีประสิทธิภาพมากขึ้น, และเป็นมิตรกับผู้ใช้มากขึ้น